package cz.semjob.learning.instances.creator;

import java.util.List;

import org.springframework.stereotype.Component;

import cz.semjob.common.attribute.value.TextDistributionAttributeValue;
import cz.semjob.document.AnnotatedDocument;
import cz.semjob.document.annotation.metadata.Entity;
import cz.semjob.document.processing.DocumentInstance;
import cz.semjob.document.processing.DocumentWord;
import cz.semjob.learning.data.TaxonomyLearningException;
import cz.semjob.learning.data.attribute.NumericInstanceAttribute;
import cz.semjob.learning.data.attribute.TextDistributionInstanceAttribute;
import cz.semjob.learning.instances.LabeledTextInstance;
import cz.semjob.learning.instances.UnlabeledTextInstance;

@Component
public class FeatureTextInstanceCreator extends BaseTextInstanceCreator
		implements IConfigurableTextInstanceCreator {

	/**
	 * 
	 */
	private static final long serialVersionUID = -4038160157601555081L;

	public static final String SENTENCE_RATIO = "SentenceRatio";
	public static final String PARAGRAPH_HEADER_DISTRIBUTION = "ParagraphHeaderDistribution";

	private TextDistributionInstanceAttribute headerDistributionAttribute;

	protected int MAX_WORDS = 4;

	public FeatureTextInstanceCreator() {
		super();

		attributesNamesList.clear();
		// attributesNamesList.add(TEXT_RELATIVE_POSITION);
		// attributesNamesList.add(PARAGRAPH_NUMBER);
		attributesNamesList.add(SENTENCE_RATIO);
		attributesNamesList.add(SENTENCE_LENGTH);
		attributesNamesList.add(WORD_COUNT);
		// attributesNamesList.add(PARAGRAPH_HEADER_DISTRIBUTION);
		attributesNamesList.add(IS_PART_OF_LIST);
		attributesNamesList.add(HEAD_POS);
		attributesNamesList.add(HEAD_GENDER);
		attributesNamesList.add(HEAD_DEPENDENCY);
		attributesNamesList.add(HEAD_CASE);
		attributesNamesList.add(LAST_WORD_POS);

		for (int i = 1; i < MAX_WORDS; i++) {
			String posAttributeName = "Word" + i + "POS";
			String dependencyAttributeName = "Word" + i + "Dependency";
			String caseAttributeName = "Word" + i + "Case";
			String numberAttributeName = "Word" + i + "Number";

			attributesNamesList.add(posAttributeName);
			attributesNamesList.add(dependencyAttributeName);
			attributesNamesList.add(caseAttributeName);
		}
	}

	public void initTextInstanceCreator() {
		super.initTextInstanceCreator();

		headerDistributionAttribute = new TextDistributionInstanceAttribute(
				PARAGRAPH_HEADER_DISTRIBUTION);
		attributesMap.put(SENTENCE_RATIO, new NumericInstanceAttribute(
				SENTENCE_RATIO));
		attributesMap.put(PARAGRAPH_HEADER_DISTRIBUTION,
				headerDistributionAttribute);

		updateAttributes(attributesNamesList);
	}

	public LabeledTextInstance createOneLabeledInstance(
			AnnotatedDocument annotatedDocument, Entity entity,
			boolean positive, List<DocumentWord> words, Object... dataSources)
			throws TaxonomyLearningException {
		LabeledTextInstance labeledTextInstance = super
				.createOneLabeledInstance(annotatedDocument, entity, positive,
						words);
		createFeatureAttributes(words, labeledTextInstance,
				annotatedDocument.getDocumentInstance());
		return labeledTextInstance;
	}

	public UnlabeledTextInstance createOneUnlabeledInstance(
			DocumentInstance documentInstance, List<DocumentWord> pathWords,
			Object... dataSources) throws TaxonomyLearningException {
		UnlabeledTextInstance unlabeledTextInstance = super
				.createOneUnlabeledInstance(documentInstance, pathWords);
		createFeatureAttributes(pathWords, unlabeledTextInstance,
				documentInstance);
		return unlabeledTextInstance;
	}

	private void createFeatureAttributes(List<DocumentWord> words,
			UnlabeledTextInstance unlabeledTextInstance,
			DocumentInstance documentInstance) throws TaxonomyLearningException {
		if (attributesNamesList.contains(SENTENCE_RATIO)) {
			double sentenceLength = words.get(0).getSentence()
					.getCharacterCount();
			double pathLength = 0d;
			for (DocumentWord documentWord : words) {
				pathLength += documentWord.getLength();
			}
			unlabeledTextInstance.addAttributeValue(SENTENCE_RATIO,
					(double) (pathLength / sentenceLength));
		}
		if (attributesNamesList.contains(PARAGRAPH_HEADER_DISTRIBUTION)) {
			String header = getParagraphHeader(words, documentInstance);
			if (unlabeledTextInstance instanceof LabeledTextInstance) {
				LabeledTextInstance labeledTextInstance = (LabeledTextInstance) unlabeledTextInstance;
				if (labeledTextInstance.isPositive()) {
					// labeled - we update distribution
					headerDistributionAttribute.addTextToDistribution(
							documentInstance.getFileName(), header);
				}
			}
			unlabeledTextInstance.addAttributeValue(
					PARAGRAPH_HEADER_DISTRIBUTION,
					new TextDistributionAttributeValue(
							PARAGRAPH_HEADER_DISTRIBUTION, header,
							headerDistributionAttribute));
			// if (unlabeledTextInstance.getClass() ==
			// UnlabeledTextInstance.class) {
			// double distribution = (Double) unlabeledTextInstance
			// .getAttributeValues()
			// .get(PARAGRAPH_HEADER_DISTRIBUTION).getAttrValue();
			// if (distribution > 0) {
			// System.out.println(distribution + ": "
			// + unlabeledTextInstance.getText());
			// }
			// }
		}
	}

	public void setMaxInstanceWordLength(int length) {
		MAX_WORDS = length;

	}

	public void setAttributesList(List<String> attributeNames) {
		updateAttributes(attributeNames);
	}

}
